using System;
using System.Collections;
using System.Data;
using System.Reflection;
//using System.Windows.Forms;

namespace HSHLogicLayer
{
	/// <summary>
	/// Summary description for DBObjectsObserver.
	/// </summary>
	public class DBObjectsObserver
	{
		private static DBObjectsObserver m_Singleton = null;				
		
		//private DateTime m_dtLastUpdate;
		private Hashtable m_allDBObjects = new Hashtable();

		/*public DateTime LastUpdate
		{
			get { return m_dtLastUpdate; }
		}*/


		private DBObjectsObserver()
		{
			//m_dtLastUpdate = UniDBSingleton.Instance().UniDB.RunSQLReturnDate("select max(last_update) from Observed_Changes");
		}

		public static DBObjectsObserver Instance()
		{
			if (m_Singleton == null) m_Singleton = new DBObjectsObserver();
			return m_Singleton;
		}

		public DBObject GetDBObject(Type DBObjectType, int PrimaryId)
		{
			String sKey = DBObjectType.Name + PrimaryId.ToString();
			if (m_allDBObjects.ContainsKey(sKey)) 
			{
				WeakReference currRef = (WeakReference)m_allDBObjects[sKey];
				if (!currRef.IsAlive) 
				{
					m_allDBObjects.Remove(sKey);
					return null;
				}
				else return (DBObject)currRef.Target;
			}
			else return null;
		}

		public DBObject GetDBObject(Type DBObjectType, int PrimaryId, object[] CtorParams)
		{
			DBObject returnObj = GetDBObject(DBObjectType, PrimaryId);
			if (returnObj == null)
			{				
				try
				{
					Type[] ctorTypes = new Type[CtorParams.Length];
					for (int nCurrParam = 0; nCurrParam < ctorTypes.Length; ++nCurrParam)
						ctorTypes[nCurrParam] = CtorParams[nCurrParam].GetType();

					ConstructorInfo ctor = DBObjectType.GetConstructor(ctorTypes);
					returnObj = (DBObject)ctor.Invoke(CtorParams);
					AddDBObject(returnObj);
				}
				catch (Exception ex)
				{
                    string msg = ex.Message;
				}
			}
			return returnObj;
		}
		
		private void AddDBObject(DBObject newDBObject)
		{
			String sKey = newDBObject.GetType().Name + newDBObject.PrimaryKey.ToString();
			if (!m_allDBObjects.ContainsKey(sKey)) 
				m_allDBObjects.Add(sKey, new WeakReference(newDBObject));
			else
			{
				if (!((WeakReference)m_allDBObjects[sKey]).IsAlive)
				{
					m_allDBObjects[sKey] = new WeakReference(newDBObject);
				}
			}
		}

		public void RefreshAll()
		{			
/*			clsParameter[] arrParam = new clsParameter[1];
			arrParam[0] = new clsParameter(LastUpdate, OracleTypes.TimeStamp);
			DataTable dtUpdates = UniDBSingleton.Instance().UniDB.RunStoredFunctionReturnDataTable("Shraga_Observer.Get_Updates", ref arrParam);			

			if (dtUpdates.Rows.Count != 0)
			{				
				m_dtLastUpdate = Convert.ToDateTime(dtUpdates.Rows[0]["NOW"]);
				
				DBObject currObject = null;
				foreach (DataRow currRow in dtUpdates.Rows)
				{
					currObject = GetDBObject(Type.GetType("Shraga.BLL." + currRow["OBJECT_TYPE"].ToString()), Convert.ToInt32(currRow["OBJECT_ID"]));
					if (currObject != null)
					{
						if (Convert.ToBoolean(currRow["REFRESH_SELF"]))
							currObject.Refresh(Convert.ToDateTime(currRow["LAST_UPDATE"]));
						else if (Convert.ToBoolean(currRow["REFRESH_MARSHALED"]))
							currObject.Refresh(Type.GetType("Shraga.BLL." + currRow["MARSHALED_TYPE"].ToString()), Convert.ToInt32(currRow["MARSHALED_ID"]));
					}
				}
			}*/
		}

		public int Count
		{
			get { return m_allDBObjects.Count; }
		}

	}
}
